﻿
Imports std

Namespace internalFunctions
    'paramters, script, any, convert to string, script source
    '           app, pointer<var>, return app
    'return, bool, whether the parse is success or not
    Public Class runtimeparse
        Inherits internalFunction

        Public Class parameters
            Public Const script As String = "script"
            Public Const app As String = "app"
        End Class

        Private Shared m As iParametersMapping = Nothing

        Shared Sub New()
            initialMapping(m, parameters.script, parameters.app)
        End Sub

        Public Sub New()
            MyBase.New("elpmis.parse", m)
        End Sub

        Protected Overrides Function invoke(ByVal ctx As context, ByRef output As bare_variable) As Boolean
            Dim script As String = Nothing
            If Not ctx.findVariableStr(parameters.script, script) Then
                raiseError("expect parameter " + parameters.script, errorHandle.errorType.user)
                Return False
            Else
                Dim app As pointer(Of pointer(Of Object)) = Nothing
                If Not ctx.findVariable(parameters.app, app) Then
                    raiseError("expect parameter " + parameters.app + " is pointer<var>.", errorHandle.errorType.user)
                    Return False
                Else
                    Dim appInstance As app = Nothing
                    If elpmis.app.parse(script, appInstance) Then
                        app.instance().setinstance(appInstance)
                        output = New bare_variable(typeDefination.bool, True)
                    Else
                        output = New bare_variable(typeDefination.bool, False)
                    End If

                    Return True
                End If
            End If
        End Function
    End Class

    'parameters, app, var, app instance, returned by runtimeparse<elpmis.parse>
    '            startFunctionName
    '            p1, parameter 1
    '            p2, parameter 2
    '            ... pn, parameter n
    '            rtn, pointer<var>, return value of app
    'return, bool, whether the invoke is success or not
    Public Class runtimeinvoke
        Inherits internalFunction

        Public Class parameters
            Public Const app As String = "app"
            Public Const startFunctionName As String = "startFunctionName"
            Public Const pbase As String = "p"
            Public Const rtn As String = "rtn"
        End Class

        Private Shared m As iParametersMapping = Nothing

        Shared Sub New()
            initialMapping(m, parameters.app, parameters.startFunctionName, parameters.rtn)
        End Sub

        Public Sub New()
            MyBase.New("elpmis.invoke", m)
        End Sub

        Protected Overrides Function invoke(ByVal ctx As context, ByRef output As bare_variable) As Boolean
            Dim app As app = Nothing
            If Not ctx.findVariable(parameters.app, app) Then
                raiseError("expect parameter " + parameters.app + " is app.", errorHandle.errorType.user)
                Return False
            Else
                Dim startFunctionName As String = Nothing
                If Not ctx.findVariableStr(parameters.startFunctionName, startFunctionName) Then
                    raiseError("expect parameter " + parameters.startFunctionName, errorHandle.errorType.user)
                    Return False
                Else
                    Dim ps As parameters_t = Nothing
                    ps = New parameters_t()

                    Dim i As Int64
                    i = 1
                    Dim this As bare_variable = Nothing
                    While ctx.findVariable(parameters.pbase + Convert.ToString(i), this)
                        ps.push_back(make_pair(CType(Nothing, String), this))
                        i += 1
                    End While

                    Dim rtn As pointer(Of pointer(Of Object)) = Nothing
                    ctx.findVariable(parameters.rtn, rtn)

                    Dim rst As bare_variable = Nothing
                    If app.invoke(startFunctionName, ps, rst) Then
                        If Not rtn Is Nothing Then
                            rtn.instance().setinstance(rst)
                        End If

                        output = New bare_variable(typeDefination.bool, True)
                    Else
                        output = New bare_variable(typeDefination.bool, False)
                    End If
                    Return True
                End If
            End If
        End Function
    End Class

    'parameters, N/A
    'return, string, the call stack to current function
    Public Class _callstack
        Inherits internalFunction

        Public Class parameters
        End Class

        Private Shared a As aliases = Nothing

        Shared Sub New()
            initialAliases(a, "callstack")
        End Sub

        Public Sub New()
            MyBase.New("elpmis.callstack", a)
        End Sub

        Protected Overrides Function invoke(ByVal ctx As context, ByRef output As bare_variable) As Boolean
            output = New bare_variable(typeDefination.string, context.callstack())
            Return True
        End Function
    End Class

    Public Class elpmisinvoke
        Inherits name_parameters_t_ps_function(Of Object)

        Public Sub New()
            MyBase.New("reflection.invoke.byname")
        End Sub

        Protected Overrides Function returnType() As typeDefination
            Return typeDefination.var
        End Function

        Protected Overrides Function invoke(ByVal ctx As context, ByVal name As String, _
                                            ByVal ps As parameters_t, ByRef o As Object) As Boolean
            Dim rtn As bare_variable = Nothing
            If ctx.invoke(name, convertor.cast(Of iParametersWithMapping)(ps), rtn) Then
                If Not rtn Is Nothing Then
                    o = rtn.value()
                End If
                Return True
            Else
                Return False
            End If
        End Function
    End Class

    Public Class quit
        Inherits noInputFunction(Of Boolean)

        Public Sub New()
            MyBase.New("quit")
        End Sub

        Protected Overloads Overrides Function invoke(ByRef o As Boolean) As Boolean
            raiseError("force quit application.")
            Return False
        End Function

        Protected Overrides Function returnType() As typeDefination
            Return typeDefination.bool
        End Function
    End Class

    Public Class hasfunction
        Inherits inputIFunction(Of String, Boolean)

        Private Shared a As aliases = Nothing

        Shared Sub New()
            initialAliases(a, "runtime.isfunction", "runtime.hasfunc", "runtime.isfunc")
        End Sub

        Public Sub New()
            MyBase.New("runtime.hasfunction", a)
        End Sub

        Protected Overrides Function finder() As iVariableFinder(Of String)
            Return string_finder()
        End Function

        Protected Overrides Function invoke(ByVal i As String, ByRef o As Boolean) As Boolean
            o = context.currentContext().findFunction(i, Nothing)
            Return True
        End Function

        Protected Overrides Function returnType() As typeDefination
            Return typeDefination.bool
        End Function
    End Class

    Public Class hasvariable
        Inherits inputIFunction(Of String, Boolean)

        Private Shared a As aliases = Nothing

        Shared Sub New()
            initialAliases(a, "runtime.isvariable", "runtime.hasvar", "runtime.isvar")
        End Sub

        Public Sub New()
            MyBase.New("runtime.hasvariable", a)
        End Sub

        Protected Overrides Function finder() As iVariableFinder(Of String)
            Return string_finder()
        End Function

        Protected Overrides Function invoke(ByVal i As String, ByRef o As Boolean) As Boolean
            o = context.currentContext().parent().findVariable(i, Nothing)
            Return True
        End Function

        Protected Overrides Function returnType() As typeDefination
            Return typeDefination.bool
        End Function
    End Class

    Public Class _typeof
        Inherits inputIFunction(Of String, String)

        Public Sub New()
            MyBase.New("typeof")
        End Sub

        Protected Overrides Function finder() As iVariableFinder(Of String)
            Return string_finder()
        End Function

        Protected Overrides Function invoke(ByVal i As String, ByRef o As String) As Boolean
            Dim ctx As context = Nothing
            ctx = context.currentContext().parent()
            If ctx.findFunction(i, Nothing) Then
                o = "function"
            Else
                Dim bv As bare_variable = Nothing
                If ctx.findVariable(i, bv) Then
                    o = typeNaming(bv.variable().type())
                Else
                    o = "null"
                End If
            End If
            Return True
        End Function

        Protected Overrides Function returnType() As typeDefination
            Return typeDefination.string
        End Function
    End Class
End Namespace
